<?php

use \GatewayWorker\Lib\Gateway;  

require_once dirname(__DIR__) . '/public.class.model.php';
class Room_Model extends Public_Model
{
	
	/***************************
			common function	
	***************************/
	
	
	/*
		断线
	*/
	public function userDisconnected($arrData)
	{
		if(!isset($arrData['gaming_roomid']) || trim($arrData['gaming_roomid']) == G_CONST::EMPTY_STRING)
		{
			return false;
		}
		if(!isset($arrData['account_id']) || trim($arrData['account_id']) == G_CONST::EMPTY_STRING)
		{
			return false;
		}
		
		$room_id 		= $arrData['gaming_roomid'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		if($this->queryOnlineStatus($room_id, $account_id)){
			$this->writeLog("[$room_id] [$account_id] is still in room");
			return true;
		}

		$this->writeLog("[$room_id] ($account_id) 离线");

		//获取房间状态
		$room_status = $this->queryRoomStatus($room_id);
		if($room_status === Redis_CONST::DATA_NONEXISTENT || $room_status == Game::RoomStatus_Closed ){	//房间已经废弃或未激活
			return true;
		}
		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);

		//没开局玩过的用户离线，自动从房间中退出
		$flag = $this->leaveSeatTransaction($room_id,$account_id);
		if(2 == $flag){			//unchecked 离座
			$account_status = Game::AccountStatus_Initial;
		} else if(1 == $flag){	//checked 离座
			$account_status = $this->queryAccountStatus($room_id, $account_id);
			if($account_status == Game::AccountStatus_Ready){	//准备状态下断线， 变为未准备
				$account_status = Game::AccountStatus_Notready;
			}
		} else {
			$account_status = Game::AccountStatus_Initial;
		}

		$this->updateAccountStatus($room_id, $account_id, $account_status );
		

		//观战功能
		$RoomGuest_Key = strtr(Redis_Const::RoomGuest_Key, $replyArr);
		$Redis_Model->lremList($RoomGuest_Key,0,[$account_id]);

		if($room_status == Game::RoomStatus_Waiting)
		{
			$ready_count = $this->queryReadyCount($room_id);
			if($ready_count < 2){
				//取消倒计时
				$this->deleteRoomTimer($room_id);
				$arr = array("result"=>0,"operation"=>"CancelStartLimitTime","data"=>array(),"result_message"=>"取消开局倒计时");
				$this->pushMessageToGroup($room_id, $arr);
			} else {
				$this->startGame($room_id);
			}
		}

		//判断是否全部人离线
		$clients_of_groupid = Gateway::getClientSessionsByGroup($room_id);
		if(count($clients_of_groupid) == 0)
		{
			$this->setupClearRoomPassiveTimer($room_id);
		}
		
		return true; 
	}
	
	
	
	/***************************
			logic function	
	***************************/
	
	/*
		创建房间
	*/
	public function createRoom($arrData)
	{

		$timestamp = time();
		$result = array();
		$return = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
        //底分
        if(!isset($data['default_score']) || !in_array($data['default_score'], [2,4,8,10,25,20,50]) )
        {
            $this->logMessage('error', "function(createRoom):lack of default_score"." in file".__FILE__." on Line ".__LINE__);
            return $this->_missingPrameterArr($operation,"default_score");
        }
		if(!isset($data['data_key']) || trim($data['data_key']) == G_CONST::EMPTY_STRING)
		{
			$this->logMessage('error', "function(createRoom):lack of data_key"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"data_key");
		}

		if(!isset($data['ticket_count']))
		{
			$this->logMessage('error', "function(createRoom):lack of ticket_count"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"ticket_count");
		}	
		if(!isset($data['chip_type']))
		{
			$this->logMessage('error', "function(createRoom):lack of chip_type"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"chip_type");
		}	
		if(!isset($data['disable_pk_score']))
		{
            $data['disable_pk_score'] = 0;
//			$this->logMessage('error', "function(createRoom):lack of disable_pk_score"." in file".__FILE__." on Line ".__LINE__);
//			return $this->_missingPrameterArr($operation,"disable_pk_score");
		}	
		if(!isset($data['disable_pk_men']))
		{
			$this->logMessage('error', "function(createRoom):lack of disable_pk_men"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"disable_pk_men");
		}	
		if(!isset($data['upper_limit']) || !in_array($data['upper_limit'], [0,500,1000,2000]) )
		{
			$this->logMessage('error', "function(createRoom):lack of upper_limit"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"upper_limit");
		}
        if(!isset($data['xipai_score'])){
//            $this->logMessage('error', "function(createRoom):lack of xipai_score"." in file".__FILE__." on Line ".__LINE__);
//            return $this->_missingPrameterArr($operation,"xipai_score");
            $data['xipai_score'] = 0;
        }
        if(!isset($data['client_name'])){
            $data['client_name'] = "wechat";
        }
        if(!isset($data['client_type'])){
            $data['client_type'] = "wechat";
        }
        if(!isset($data['daikai_id'])){
            $data['daikai_id'] = 0;
        }
        //获取随机房间号
        $newRoomNumber = $this->getNewRoomNumber();
		$data_key = $data['data_key'];
		$spend_ticket_count = $data['ticket_count'];


		$total_num = 12 * $spend_ticket_count;   //9人房   12/24局
        $this->logMessage("error",$total_num);
        $default_score = $data['default_score'];
		$chip_type = $data['chip_type'];
		$disable_pk_score = $data['disable_pk_score'];
		$disable_pk_men = $data['disable_pk_men'];
		$disable_look = $data['disable_look'];
		$upper_limit = $data['upper_limit'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}

		//获取维护公告
		$alert_type = -1;
		$announcement_result = $this->getGameAnnouncement($account_id);
		if(is_array($announcement_result))
		{
			$alert_type = $announcement_result['alert_type'];
			$alert_text = $announcement_result['alert_text'];
		}
		if($alert_type == 4)
		{
				$result['alert_type'] = $alert_type;
				return array("result"=>"-1","operation"=>$operation,"data"=>$result,"result_message"=>$alert_text); 
		}
		
		$MMYSQL = $this->initMysql();

		//判断房卡余额
		$my_ticket_count = $MMYSQL->select("ticket_count")->from("room_ticket")->where("account_id=".$account_id)->single();
		$this->writeLog("($account_id) 牌券:" . $my_ticket_count);
		if($my_ticket_count >= $spend_ticket_count){

		} else {
			$this->writeLog("($account_id) 牌券不足");
			$result['alert_type'] = 1;	//1房卡不足
			return array("result"=>"1","operation"=>$operation,"data"=>$result,"result_message"=>"房卡不足"); 
		}

		//判断房间申请记录是否存在
		$room_where = 'data_key="'.$data_key.'"';
		$room_sql = 'select room_id,room_number,account_id,is_close from '.Room.' where '.$room_where;
		$room_query = $MMYSQL->query($room_sql);
		if(!is_array($room_query) || count($room_query) == 0 )
		{
			$room_aid = $account_id;
			$is_close = G_CONST::IS_FALSE;
			
			$r_array['create_time'] = $timestamp;
			$r_array['create_appid'] = "aid_".$account_id;
			$r_array['update_time'] = $timestamp;
			$r_array['update_appid'] = "aid_".$account_id;
			$r_array['is_delete'] = G_CONST::IS_FALSE;
			$r_array['data_key'] = $data_key;
			$r_array['account_id'] = $room_aid;
			$r_array['is_close'] = G_CONST::IS_FALSE;
			$r_array['game_type'] = Game::Game_Type;
            $r_array['new_room_number'] = $newRoomNumber;
            $r_array['client_name'] = $data['client_name'];
            $r_array['client_type'] = $data['client_type'];
			$r_array['daikai_id'] = $data['daikai_id'];
			$room_id = $MMYSQL->insertReturnID(Room,$r_array);
			if($room_id > 0)
			{
				//$room_number = 10000 + $room_id;
				$room_number = 100000 + $room_id * 10 + mt_rand(1,12);
			}
			else
			{
				$this->logMessage('error', "function(createRoom):用户".$account_id." 创建房间失败："." in file".__FILE__." on Line ".__LINE__);
				return array("result"=>"-1","operation"=>$operation,"data"=>$result,"result_message"=>"创建房间失败"); 
			}

			$num_updateSql = 'update '.Room.' set room_number="'.$room_number.'" where room_id='.$room_id;
			$num_updateQuery = $MMYSQL->query($num_updateSql);
		}
		else
		{
			$room_id = $room_query[0]['room_id'];
			$room_number = $room_query[0]['room_number'];
			$room_aid = $room_query[0]['account_id'];
			$is_close = $room_query[0]['is_close'];
		}
		
		//添加房间信息到redis
		$Redis_Model = Redis_Model::getModelObject();
		$this->logMessage("error",$room_id);
		$replyArr = array("[roomid]"=>$room_id);
		$Room_Key = strtr(Redis_Const::Room_Key, $replyArr);
		
		$r_mkv[Redis_Const::Room_Field_Number] = $room_number;	//房间号
		$r_mkv[Redis_Const::Room_Field_GameRound] = 1;			//游戏轮数
		$r_mkv[Redis_Const::Room_Field_GameNum] = 0;			//游戏第几局
		$r_mkv[Redis_Const::Room_Field_TotalNum] = $total_num;
		$r_mkv[Redis_Const::Room_Field_Status] = Game::RoomStatus_Waiting;				//房间状态，1等待、2进行中、3关闭
		$r_mkv[Redis_Const::Room_Field_DefaultScore] = $default_score;		//开局默认分数

		$r_mkv[Redis_Const::Room_Field_TicketCount] = $spend_ticket_count;
		$r_mkv[Redis_Const::Room_Field_ChipType] = $chip_type;
		$r_mkv[Redis_Const::Room_Field_DisablePkScore] = $disable_pk_score;
		$r_mkv[Redis_Const::Room_Field_DisableLook] = $disable_look;
		$r_mkv[Redis_Const::Room_Field_DisablePkMen] = $disable_pk_men;
		$r_mkv[Redis_Const::Room_Field_UpperLimit] = $upper_limit;
		$r_mkv[Redis_Const::Room_Field_Creator] = $account_id;  //房间创建者
        $r_mkv[Redis_CONST::Room_Field_XiPai]        = $data['xipai_score'];
		$r_mkv[Redis_Const::Room_Field_StartTime] = -1;
        $r_mkv[Redis_CONST::Room_Field_NewNumber] = $newRoomNumber;
		$mset_result = $Redis_Model->hmsetField($Room_Key,$r_mkv);
        $RedisLog_Model = Redis_Model::getModelObjectLogs();
        $RedisLog_Model->hmsetField(Redis_CONST::Room_New_Key,[$newRoomNumber=>json_encode(["room_number"=>$room_number,"game_type"=>Game::Game_Type, "create_time"=>date('Y-m-d H:i:s',$timestamp),"client_name"=>$data['client_name']])]);

        $result['room_id'] = $room_id;
		$result['room_number'] = $room_number;
		$result['is_close'] = $is_close;

		//扣除房卡  房主扣卡模式
		if(Config::Ticket_Mode == 2){
//			$game_multi = Config::GameUser_MaxCount==12 ? 2 : 1;
//			$this->balanceTicket($room_id, $account_id, $spend_ticket_count * $game_multi * Config::Ticket_Multi);
            $this->balanceTicket($room_id, $account_id, $spend_ticket_count * Config::Ticket_Multi);
		}
		//观战功能 建房时设定清房定时器
		$this->setupClearRoomPassiveTimer($room_id);
		$this->writeLog("[$room_id] ($account_id) 创建房间".$room_number);
		return array("result"=>OPT_CONST::SUCCESS,"operation"=>$operation,"data"=>$result,"result_message"=>"创建房间");  
	}
	

    /*
    * 进房并发
    */
    protected function joinRoomTransaction($room_id,$account_id,$max_count)
    {
        $Redis_Model = Redis_Model::getModelObject();
        $replyArr = array("[roomid]"=>$room_id);
        $key = strtr(Redis_Const::RoomSequence_Key, $replyArr);

        $redisAuth = $Redis_Model->pingRedisAuth();
        if($redisAuth === G_CONST::EMPTY_STRING || !is_object($redisAuth))
        {
            $this->logMessage('error', "function(joinRoomTransaction):redisAuth is empty string"." in file".__FILE__." on Line ".__LINE__);
            return false;
        }

        $success = false;
        $options = array(
            'cas'   => true,    // Initialize with support for CAS operations
            'watch' => $key,    // Key that needs to be WATCHed to detect changes
            'retry' => 3,       // Number of retries on aborted transactions, after
                                // which the client bails out with an exception.
        );

        $redisAuth->transaction($options, function ($tx) use ($key,$account_id, $max_count, &$success) {
            $result = $tx->zrange($key,0,-1,'withscores');
            if(is_array($result)) {
                if(count($result) >= $max_count){
                    $this->writeLog("joinRoom: accountid".$account_id." 人数已满 ".__FILE__.__LINE__);
                    $success = false;
                } else {
                    for($serial_num=1;$serial_num<=$max_count;$serial_num++){
                        if(array_search($serial_num,$result) === false){
                            $tx->multi();   // With CAS, MULTI *must* be explicitly invoked.
                            $zadd_result = $tx->zadd($key,$serial_num,-$account_id);
                            $success = $serial_num;
                            break;
                        }
                    }
                }
            } else {
                $this->writeLog("joinRoom:zrange result error ".__FILE__.__LINE__);
                $success = false;
            }
        });
        return $success;
    }
    public function getNewRoomNumber(){
        $ti = microtime();
        list($s,$m) = explode(" ", $ti);
        $newRoomNumber = substr($m + substr($s,2), 4);
        if ($newRoomNumber <= 100000) $newRoomNumber += 100000;
        $RedisLog_Model = Redis_Model::getModelObjectLogs();
        if ($RedisLog_Model->hexistsField('RoomNumber',$newRoomNumber) == Redis_CONST::Key_Nonexistent){
            return $newRoomNumber;
        }else{
            return $this->getNewRoomNumber();
        }
    }
	/*
		进入房间
	*/
	public function joinRoom($arrData)
	{
		$timestamp = time();
		$result = array();
		$return = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!(isset($data['room_number'])&& $data['room_number'] > 0) )
		{
			$this->logMessage('error', "function(joinRoom):lack of room_number"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_number");
		}
		
		$room_number = $data['room_number'];
		
		//判断房间是否存在
		$MMYSQL = $this->initMysql();
		$room_sql = 'select room_id,account_id,is_close from '.Room.' where room_number='.$room_number;
		$room_row = $MMYSQL->row($room_sql);
		if(!$room_row){
			$this->logMessage('error', "function(joinRoom):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");  
		} else {
			$room_id = $room_row['room_id'];
			if($room_row['is_close']){
				$result = array('room_status'=>4);
				return array("result"=>0, "operation"=>$operation,"data"=>$result,"result_message"=>"房间已关闭"); 
			}
		}
		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);
		//总分数
		$RoomScore_Key = strtr(Redis_Const::RoomScore_Key, $replyArr);
			
		//判断用户是否已加入房间
		$serial_num = $this->querySerialNum($room_id, $account_id);
		if($serial_num > 0)		//已加入
		{
			//获取分数
			$rScore_score = $Redis_Model->hgetField($RoomScore_Key,$account_id);
			$account_status = $this->queryAccountStatus($room_id, $account_id);
		}
		else	//未加入
		{
			$serial_num = $this->joinRoomTransaction($room_id,$account_id, Config::GameUser_MaxCount);
			if(!$serial_num){
				$result['alert_type'] = 2;
				return array("result"=>"1","operation"=>$operation,"data"=>$result,"result_message"=>"房间人数已满"); 
			}
			

			//添加默认分数
			$rScore_score = 0;
			$rScore_mkv[$account_id] = $rScore_score;
			$hmset_result = $Redis_Model->hmsetField($RoomScore_Key,$rScore_mkv);

			//首次进房初始状态
			$account_status =  Game::AccountStatus_Initial;
			$AccountStatus_Key = strtr(Redis_Const::AccountStatus_Key, $replyArr);
			$mkv[$account_id] = $account_status;
			$mset_result = $Redis_Model->hmsetField($AccountStatus_Key,$mkv);

		}
		
		//绑定用户UID
		$RoomUser_UID = strtr(Game::RoomUser_UID, $replyArr);
		Gateway::bindUid($client_id, $RoomUser_UID);
		Gateway::joinGroup($client_id, $room_id);
		
		//获取房间当前局数
		$game_num = $this->queryGameNumber($room_id);
		$room_status = $this->queryRoomStatus($room_id);
		$room_ary['room_id'] = $room_id;
		$room_ary['room_number'] = $room_number;
		$room_ary['room_status'] = $room_status;
		$room_ary['account_score'] = $rScore_score;
		$room_ary['account_status'] = $account_status;
		$room_ary['online_status'] = $this->queryOnlineStatus($room_id, $account_id);

		$room_ary['serial_num'] = $serial_num;
		$room_ary['game_num'] = $game_num;
		$room_ary['total_num'] = $this->queryTotalNum($room_id);

		$room_ary['ticket_checked'] = $this->queryTicketChecked($room_id, $account_id);
		$room_ary['scoreboard'] = $this->queryScoreboard($room_id);

		$card_info = array();
		$card_type = 0;
		if($this->querySeenCard($room_id, $account_id)){	//已经看过牌的
			$card_info = $this->queryCardInfo($room_id, $account_id);
			$value = $this->caculateCardValue($room_id, $account_id);
			$card_type = substr($value, 0, 1);
		}

		$room_ary['cards'] = $card_info;
		$room_ary['card_type'] = $card_type;

		$room_ary['benchmark'] = $this->queryBenchmark($room_id);
		$room_ary['pool_score'] = $this->queryPoolScore($room_id);



		$setting = $this->queryRoomSetting($room_id);
		$room_ary['ticket_count'] =isset($setting[Redis_Const::Room_Field_TicketCount]) ?$setting[Redis_Const::Room_Field_TicketCount]:1;
		$room_ary['chip_type'] = isset($setting[Redis_Const::Room_Field_ChipType])?$setting[Redis_Const::Room_Field_ChipType]:1;
		$room_ary['disable_pk_score'] =isset($setting[Redis_Const::Room_Field_DisablePkScore]) ?$setting[Redis_Const::Room_Field_DisablePkScore]:0;
		$room_ary['disable_look'] =isset($setting[Redis_Const::Room_Field_DisableLook]) ?$setting[Redis_Const::Room_Field_DisableLook]:0;

		$room_ary['disable_pk_men'] =isset($setting[Redis_Const::Room_Field_DisablePkMen]) ?$setting[Redis_Const::Room_Field_DisablePkMen]:0;
		$room_ary['upper_limit'] =isset($setting[Redis_Const::Room_Field_UpperLimit]) ?$setting[Redis_Const::Room_Field_UpperLimit]:1000;
        $room_ary['xipai_score']    = $setting[Redis_Const::Room_Field_XiPai];
        $room_ary['creator_id'] =$setting[Redis_Const::Room_Field_Creator];
		//推送房间信息
		$room_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>$operation,"data"=>$room_ary,"result_message"=>"入房成功");
		$this->pushMessageToCurrentClient($room_return);
		
		//返回所有玩家状态给进房玩家
		$allGamer = $this->getGamerInfo($room_id);
		if(is_array($allGamer))
		{
			$currentGamer_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>"AllGamerInfo","data"=>$allGamer,"result_message"=>"所有玩家状态");
			$this->pushMessageToCurrentClient($currentGamer_return);
		}

		$this->notyfyPlayingStatus($room_id, $account_id);
		
		//观战功能  从观战列表删除
		$RoomGuest_Key = strtr(Redis_Const::RoomGuest_Key, $replyArr);
		$Redis_Model->lremList($RoomGuest_Key,0,[$account_id]);
		//返回所有观战者给当前玩家
		$allGuest = $this->getGuestInfo($room_id);
		if(is_array($allGuest))
		{
			$currentGamer_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>"AllGuestInfo","data"=>$allGuest,"result_message"=>"所有观战者状态");
			$this->pushMessageToCurrentClient($currentGamer_return);
		}

		//推送当前玩家状态给其他玩家
		$currentGamer = $this->getGamerInfo($room_id,$account_id);
		if(is_array($currentGamer))
		{
			$currentGamer_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>"UpdateGamerInfo","data"=>$currentGamer,"result_message"=>"某玩家状态");
			$this->pushMessageToGroup($room_id, $currentGamer_return, $client_id);
		}

		//显示房间目前的倒计时
		$limit = $game_num > 0 ? Game::LimitTime_Ready : Game::LimitTime_StartGame;

		if($room_status == Game::RoomStatus_Waiting && ($countdown = $this->queryCountdown($room_id, $limit)) > 0){
			$arr = array("result"=>0,"operation"=>"StartLimitTime","data"=>array('limit_time' => $countdown),"result_message"=>"开始倒计时");
			$this->pushMessageToCurrentClient($arr);
		}
		
		//保存用户当前房间,用户ID
		$_SESSION['gaming_roomid'] = $room_id;
		$_SESSION['account_id'] = $account_id;
		
		$this->writeLog("[$room_id] $account_id 进入房间");
		return OPT_CONST::NO_RETURN;
	}

	protected function notyfyPlayingStatus($room_id, $account_id)
	{
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);
		$active_user =  $this->queryActiveUser($room_id);
		if($active_user != -1){

			$can_open = 0;
			$pk_user = array();
			if($this->pkChipConditon($room_id, $active_user)){
				$pk_user = $this->queryPkUser($room_id, $active_user);
				if(count($pk_user) > 0){
					$can_open = 1;
				}
			}
			
			//通知:哪位正进行下注
			$noty_arr = array(
				'account_id' => $active_user,
				'playing_status' => Game::PlayingStatus_Betting,
				'limit_time'	 => $this->queryCountdown($room_id, Game::LimitTime_Betting),
				'can_open' => $can_open,
				'pk_user' => $pk_user ,
				'can_look' => $this->lookConditon($room_id, $active_user)
				);
			$msg_arr = array("result"=>0,"operation"=>"NotyChooseChip","data"=>$noty_arr,"result_message"=>"通知下注");
			$this->pushMessageToCurrentClient($msg_arr);
		}
	}

	/*
		观战功能 进入观战
	*/
	public function guestRoom($arrData)
	{
		$timestamp = time();
		$result = array();
		$return = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!(isset($data['room_number'])&& $data['room_number'] > 0) )
		{
			$this->writeLog(__FUNCTION__.":lack of room_number"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_number");
		}
		
		$room_number = $data['room_number'];
		
		//判断房间是否存在
		$MMYSQL = $this->initMysql();
		$room_sql = 'select room_id,account_id,is_close from '.Room.' where room_number='.$room_number;
		$room_row = $MMYSQL->row($room_sql);
		if(!$room_row){
			$this->writeLog(__FUNCTION__.":room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");  
		} else {
			$room_id = $room_row['room_id'];
			if($room_row['is_close']){
				$result = array('room_status'=>4);
				return array("result"=>0, "operation"=>$operation,"data"=>$result,"result_message"=>"房间已关闭"); 
			}
		}
		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);
		$RoomGuest_Key = strtr(Redis_Const::RoomGuest_Key, $replyArr);

		$guests = $this->queryGuestList($room_id);
		//判断用户是否已加入观战
		if(!in_array($account_id, $guests)){
			$Redis_Model->pushList(1,0,$RoomGuest_Key,[$account_id]);
		}
		
		//绑定用户UID
		$RoomUser_UID = strtr(Game::RoomUser_UID, $replyArr);
		Gateway::bindUid($client_id, $RoomUser_UID);
		Gateway::joinGroup($client_id, $room_id);
		
		//获取房间当前局数
		$setting = $this->queryRoomSetting($room_id);
		$game_num = $setting[Redis_CONST::Room_Field_GameNum];
		$total_num = $setting[Redis_CONST::Room_Field_TotalNum];
		$room_status = $setting[Redis_CONST::Room_Field_Status];
		$scoreboard_str = $setting[Redis_CONST::Room_Field_Scoreboard];
		$scoreboard = json_decode($scoreboard_str);


		$room_ary['room_id'] = $room_id;
		$room_ary['room_status'] = $room_status;
		$room_ary['game_num'] = $game_num;
		$room_ary['total_num'] = $total_num;
		$room_ary['scoreboard'] = $scoreboard;

		$room_ary['benchmark'] = $this->queryBenchmark($room_id);
		$room_ary['pool_score'] = $this->queryPoolScore($room_id);
        $room_ary['creator_id'] =$setting[Redis_Const::Room_Field_Creator];
		//推送房间信息
		$room_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>$operation,"data"=>$room_ary,"result_message"=>"入房成功");
		$this->pushMessageToCurrentClient($room_return);
		
		//在座->观战
		$try_start = false;
		$flag = $this->leaveSeatTransaction($room_id,$account_id);
		if($flag > 0){
			$try_start = true;
			$this->writeLog("[$room_id] ($account_id) 玩家变为观战者");
		}

		//返回所有玩家状态给当前玩家
		$allGamer = $this->getGamerInfo($room_id);
		if(is_array($allGamer))
		{
			$currentGamer_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>"AllGamerInfo","data"=>$allGamer,"result_message"=>"所有玩家状态");
			$this->pushMessageToCurrentClient($currentGamer_return);
		}

		$this->notyfyPlayingStatus($room_id, $account_id);
		
		//返回所有观战者给当前玩家
		$allGuest = $this->getGuestInfo($room_id);
		if(is_array($allGuest))
		{
			$currentGamer_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>"AllGuestInfo","data"=>$allGuest,"result_message"=>"所有观战者状态");
			$this->pushMessageToCurrentClient($currentGamer_return);
		}
		
		//推送当前观战者给其他玩家
		$account_sql = 'select nickname,headimgurl from '.WX_Account.' where account_id="'.$account_id.'"';
		$row = $MMYSQL->row($account_sql);
		if($row){
			$guest = array(
				'account_id' => $account_id,
				'nickname'   => $row['nickname'],
				'headimgurl' => $row['headimgurl'],
				'is_guest'   => "1"
				);
			$guest_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>"UpdateGuestInfo","data"=>$guest,"result_message"=>"某观战者状态");
			$this->pushMessageToGroup($room_id, $guest_return, $client_id);
		} else {
			$this->writeLog("推送当前观战者:account($account_id) not exist".__FILE__.__LINE__);
		}

		//显示房间目前的倒计时
		$limit = $game_num > 0 ? Game::LimitTime_Ready : Game::LimitTime_StartGame;
		if($room_status == Game::RoomStatus_Waiting && ($countdown = $this->queryCountdown($room_id, $limit)) > 0){
			$arr = array("result"=>0,"operation"=>"StartLimitTime","data"=>array('limit_time' => $countdown),"result_message"=>"开始倒计时");
			$this->pushMessageToCurrentClient($arr);
		}
		
		//保存用户当前房间,用户ID
		$_SESSION['gaming_roomid'] = $room_id;
		$_SESSION['account_id'] = $account_id;
		
		if($try_start){
			$this->startGame($room_id);
		}

		$this->writeLog("[$room_id] ($account_id) 观战");
		return OPT_CONST::NO_RETURN;
	}
	/*
		获取观战者
	*/
	protected function getGuestInfo($room_id)
	{
		$result = array();
		$MMYSQL = $this->initMysql();

		//观战者列表
		$guests = $this->queryGuestList($room_id);

		if(count($guests)>0){
			$account_sql = 'select account_id,nickname,headimgurl from '.WX_Account.' where account_id in ('.implode(",", $guests).')';
			$rows = $MMYSQL->query($account_sql);
			if(is_array($rows)){
				foreach ($rows as $item) {
					$info['account_id'] = $item['account_id'];
					$info['nickname'] = $item['nickname'];
					$info['headimgurl'] = $item['headimgurl'];
					$result[] = $info;
				}
			}
		}
		return $result;
	}

	/*
		拉取房间信息
	*/
	public function pullRoomInfo($arrData)
	{
		$result = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!(isset($data['room_id'])&& $data['room_id'] > 0) )
		{
			$this->logMessage('error', "function(pullRoomInfo):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_id");
		}
		
		$room_id = $data['room_id'];

		$is_legal = $this->checkRequestClientLegal($client_id,$room_id,$account_id);
		if(!$is_legal)
		{
			$this->logMessage('error', "function(checkRequestClientLegal):illegal opt: account_id($account_id) room_id($room_id)"." in file".__FILE__." on Line ".__LINE__);
			//推送强制下线
			$illegal_message = $this->_JSON(array("result"=>"-203","result_message"=>"illegal opt")); 
			Gateway::sendToCurrentClient($illegal_message);
			return OPT_CONST::NO_RETURN;
		}
		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);
		//总分数
		$RoomScore_Key = strtr(Redis_Const::RoomScore_Key, $replyArr);
			
		//判断用户是否已加入房间
		$serial_num = $this->querySerialNum($room_id, $account_id);
		if($serial_num > 0)		//已加入
		{
			//获取分数
			$rScore_score = $Redis_Model->hgetField($RoomScore_Key,$account_id);
			$account_status = $this->queryAccountStatus($room_id, $account_id);
		}
		else	//未加入
		{
			$this->logMessage('error', "function(pullRoomInfo):account($account_id) not join room"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"用户未加入房间"); 
		}
		
		$room_ary['account_score'] = $rScore_score;
		$room_ary['account_status'] = $account_status;
		$room_ary['online_status'] = $this->queryOnlineStatus($room_id, $account_id);

		$room_ary['serial_num'] = $serial_num;

		$room_ary['ticket_checked'] = $this->queryTicketChecked($room_id, $account_id);

		$card_info = array();
		$card_type = 0;
		if($this->querySeenCard($room_id, $account_id)){	//已经看过牌的
			$card_info = $this->queryCardInfo($room_id, $account_id);
			$value = $this->caculateCardValue($room_id, $account_id);
			$card_type = substr($value, 0, 1);
		}

		$room_ary['cards'] = $card_info;
		$room_ary['card_type'] = $card_type;

		$room_ary['benchmark'] = $this->queryBenchmark($room_id);
		$room_ary['pool_score'] = $this->queryPoolScore($room_id);

		$setting = $this->queryRoomSetting($room_id);
		$room_ary['chip_type'] = isset($setting[Redis_Const::Room_Field_ChipType])?$setting[Redis_Const::Room_Field_ChipType]:1;
		
		//返回所有玩家状态
		$allGamer = $this->getGamerInfo($room_id);
		if(!is_array($allGamer))
		{
			$this->logMessage('error', "function(pullRoomInfo):room($room_number) no player"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间没有其他用户"); 
		}

		$pull_return = array("result"=>OPT_CONST::SUCCESS,"operation"=>$operation,"data"=>$room_ary,"result_message"=>"拉取房间信息","all_gamer_info"=>$allGamer);

		$this->pushMessageToCurrentClient($pull_return);

		$this->notyfyPlayingStatus($room_id, $account_id);

		$this->logMessage('error', "function(pullRoomInfo):用户$account_id 拉取房间$room_id 信息"." in file".__FILE__." on Line ".__LINE__);
		$this->logMessage('error', "function(pullRoomInfo):pull_return:".json_encode($pull_return). " in file".__FILE__." on Line ".__LINE__);

		return OPT_CONST::NO_RETURN;
	}
	
	/*
		获取房间所有用户
	*/
	protected function getGamerInfo($room_id,$account_id=-1)
	{
		$result = array();
		//获取房间所有用户
		$gamer_query = $this->queryRoomMembers($room_id, true);
		if(count($gamer_query) > 0)
		{
			$MMYSQL = $this->initMysql();
			foreach($gamer_query as $gamer_id=>$serial_num)
			{
				//获取玩家信息
				$account_where = 'account_id="'.$gamer_id.'"';
				$account_sql = 'select nickname,headimgurl from '.WX_Account.' where '.$account_where;
				$account_query = $MMYSQL->query($account_sql);
				if(!is_array($account_query) || count($account_query) == 0 )
				{
					$this->logMessage('error', "function(getGamerInfo):account($gamer_id) not exist"." in file".__FILE__." on Line ".__LINE__);
					return false;
				}
				$info['serial_num'] = $serial_num;
				$info['account_id'] = $gamer_id;
				$info['nickname'] = $account_query[0]['nickname'];
				$info['headimgurl'] = $account_query[0]['headimgurl'];
				
				
				//获取玩家当前积分
				$rScore_score = $this->queryAccountScore($room_id, $gamer_id);
				if(Redis_CONST::DATA_NONEXISTENT === $rScore_score)
				{
					$this->logMessage('error', "function(getGamerInfo):account($gamer_id) score not exist"." in file".__FILE__." on Line ".__LINE__);
					return false;
				}
				$info['account_score'] = $rScore_score;
				
				//获取玩家当前状态
				$rStatus = $this->queryAccountStatus($room_id, $gamer_id);
				if(Redis_CONST::DATA_NONEXISTENT === $rStatus)
				{
					$this->logMessage('error', "function(getGamerInfo):account($gamer_id) status not exist"." in file".__FILE__." on Line ".__LINE__);
					return false;
				}
				$info['account_status'] = $rStatus;
				$info['online_status'] = $this->queryOnlineStatus($room_id, $gamer_id);
				$info['ticket_checked'] = $this->queryTicketChecked($room_id, $gamer_id);
				
				if($account_id == $gamer_id)
				{
					return $info;
				}
				
				$result[] = $info;
				
			}
		}
		
		return $result;
	}


	/*
		进房之前的查询
	*/
	public function prepareJoinRoom($arrData)
	{
		$result = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!(isset($data['room_number'])&& $data['room_number'] > 0) )
		{
			$this->logMessage('error', "function(PrepareJoinRoom):lack of room_number"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_number");
		}
		
		$room_number = $data['room_number'];
		
		//判断房间是否存在
		$MMYSQL = $this->initMysql();
		$room_sql = 'select room_id,account_id,is_close from '.Room.' where room_number='.$room_number;
		$room_row = $MMYSQL->row($room_sql);
		if(!$room_row){
			$this->logMessage('error', "function(joinRoom):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");  
		} else {
			$room_id = $room_row['room_id'];
			if($room_row['is_close']){
				$result = array('room_status'=>4);
				return array("result"=>0, "operation"=>$operation,"data"=>$result,"result_message"=>"房间已关闭"); 
			}
		}

		//房间参数
		$user_count = 0;
		$alert_text = "";
		$room_status = $this->queryRoomStatus($room_id);
		$setting = $this->queryRoomSetting($room_id);
		$ticket_count=isset($setting[Redis_Const::Room_Field_TicketCount]) ?$setting[Redis_Const::Room_Field_TicketCount]:1;
		$chip_type= isset($setting[Redis_Const::Room_Field_ChipType])?$setting[Redis_Const::Room_Field_ChipType]:1;
		$disable_pk_score=isset($setting[Redis_Const::Room_Field_DisablePkScore]) ?$setting[Redis_Const::Room_Field_DisablePkScore]:0;
		$disable_pk_men=isset($setting[Redis_Const::Room_Field_DisablePkMen]) ?$setting[Redis_Const::Room_Field_DisablePkMen]:0;
		$disable_look=isset($setting[Redis_Const::Room_Field_DisableLook]) ?$setting[Redis_Const::Room_Field_DisableLook]:0;
		$upper_limit   =isset($setting[Redis_Const::Room_Field_UpperLimit]) ?$setting[Redis_Const::Room_Field_UpperLimit]:1000;
		$room_array = array(
			'user_count'=>$user_count,
			'alert_text' => $alert_text,
			'room_status' => $room_status,
			'ticket_count' => $ticket_count,
            'default_score'  => $setting[Redis_Const::Room_Field_DefaultScore],
			'chip_type' => $chip_type,
			'disable_pk_score' => $disable_pk_score,
			'disable_pk_men' => $disable_pk_men,
			'disable_look' => $disable_look,
			'upper_limit' => $upper_limit,
            'xipai_score'    => $setting[Redis_Const::Room_Field_XiPai],
            'creator_id'     => $setting[Redis_Const::Room_Field_Creator],
			);

		//获取维护公告
		$alert_type = -1;
		$announcement_result = $this->getGameAnnouncement($account_id);
		if(is_array($announcement_result))
		{
			$alert_type = $announcement_result['alert_type'];
			$alert_text = $announcement_result['alert_text'];
		}
		if($alert_type == 4)
		{
				$room_array['alert_type'] = $alert_type;
				return array("result"=>"1","operation"=>$operation,"data"=>$room_array,"result_message"=>$alert_text); 
		}

		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);
		$RoomGuest_Key = strtr(Redis_Const::RoomGuest_Key, $replyArr);

		//房间人
		$room_users = array();
		$is_member = false;
		//获取房间所有用户
		$gamer_query = $this->queryRoomMembers($room_id);
		if(count($gamer_query)>0)
		{
			$account_sql = 'select account_id,nickname from '.WX_Account.' where account_id in ('.implode(",", $gamer_query).')';
			$rows = $MMYSQL->query($account_sql);
			if(is_array($rows)){
				foreach ($rows as $item) {
					$room_users[] = $item['nickname'];
					$user_count++;
					if($item['account_id'] == $account_id){
						$is_member = true;
					}
				}
			}
		}

		//观战功能
		//获取房间参观者数量
		$guest_count = $Redis_Model->llenList($RoomGuest_Key);
		$room_array['is_member'] = $is_member;
		$room_array['can_join'] = $user_count < Config::GameUser_MaxCount;
		$room_array['can_guest'] = $guest_count < Config::Guest_MaxCount;
		$room_array['room_users'] = $room_users;

		return array("result"=>"0","operation"=>$operation,"data"=>$room_array,"result_message"=>"进房询问");
	}

	protected function getGameAnnouncement($account_id)
	{
		//var_dump($account_id);

		$timestamp = time();

		$MMYSQL = $this->initMysql();

		$game_type = Game::Game_Type;

		$announcement_where = 'game_type='.$game_type.' and announce_time<='.$timestamp.' and end_time>'.$timestamp.' and is_delete=0';
		$announcement_sql = 'select announce_time,service_time,end_time,announce_text,service_text from '.Game_Announcement.' where '.$announcement_where;
		$announcement_query = $MMYSQL->query($announcement_sql);
		if(is_array($announcement_query) && count($announcement_query) > 0)
		{
			$announce_time = $announcement_query[0]['announce_time'];
			$service_time = $announcement_query[0]['service_time'];
			$end_time = $announcement_query[0]['end_time'];
			$announce_text = $announcement_query[0]['announce_text'];
			$service_text = $announcement_query[0]['service_text'];

			if($timestamp >= $service_time)
			{
				$array['alert_type'] = 4;
				$array['alert_text'] = $service_text;
			}
			else
			{
				$array['alert_type'] = 4;
				$array['alert_text'] = $announce_text;
			}

			//获取白名单用户
			$whilelist_sql = 'select data_id from '.Game_Whilelist.' where account_id='.$account_id.' and is_delete=0';
			$whilelist_query = $MMYSQL->query($whilelist_sql);
			if(is_array($whilelist_query) && count($whilelist_query) > 0)
			{
				$this->logMessage('error', "function(getGameAnnouncement):白名单用户:".$account_id." in file".__FILE__." on Line ".__LINE__);
				return true;
			}
			else
			{
				return $array;
			}
		}

		return true;
	}
	
	
	/*
		准备操作
	*/
	public function readyStart($arrData)
	{
		$timestamp = time();
		$result = array();
		$return = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!isset($data['room_id']) || trim($data['room_id']) == G_CONST::EMPTY_STRING)
		{
			$this->logMessage('error', "function(readyStart):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_id");
		}
		
		$room_id = $data['room_id'];

		$is_legal = $this->checkRequestClientLegal($client_id,$room_id,$account_id);
		if(!$is_legal)
		{
			$this->logMessage('error', "function(checkRequestClientLegal):illegal opt: account_id($account_id) room_id($room_id)"." in file".__FILE__." on Line ".__LINE__);
			//推送强制下线
			$illegal_message = $this->_JSON(array("result"=>"-203","result_message"=>"illegal opt")); 
			Gateway::sendToCurrentClient($illegal_message);
			return OPT_CONST::NO_RETURN;
		}
		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);
		
		//获取玩家当前状态，是否未准备
		$rStatus = $this->queryAccountStatus($room_id, $account_id);
		if(Redis_CONST::DATA_NONEXISTENT === $rStatus || !in_array($rStatus, [Game::AccountStatus_Initial, Game::AccountStatus_Notready])  )
		{
			$this->writeLog("function(readyStart):account($account_id) status($rStatus) invalid"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"状态异常"); 
		}
		
		//更新用户状态
		$rStatus = Game::AccountStatus_Ready;
		$this->updateAccountStatus($room_id, $account_id, $rStatus);

		$this->startGame($room_id);
		
		return OPT_CONST::NO_RETURN;
	}
	
	/*
		取消准备操作
	*/
	public function readyCancel($arrData)
	{
		$timestamp = time();
		$result = array();
		$return = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!isset($data['room_id']) || trim($data['room_id']) == G_CONST::EMPTY_STRING)
		{
			$this->logMessage('error', "function(readyCancel):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_id");
		}
		
		$room_id = $data['room_id'];
		
		$Redis_Model = Redis_Model::getModelObject();
		$replyArr = array("[roomid]"=>$room_id,"[accountid]"=>$account_id);
		
		//设置当前状态，已准备
		//更新用户状态
		$rStatus = Game::AccountStatus_Notready;
		$this->updateAccountStatus($room_id, $account_id, $rStatus);

		$ready_count = $this->queryReadyCount($room_id);
		if($ready_count < 2){
			//取消倒计时
			$this->deleteRoomTimer($room_id);
			$arr = array("result"=>0,"operation"=>"CancelStartLimitTime","data"=>array(),"result_message"=>"取消开局倒计时");
			$this->pushMessageToGroup($room_id, $arr);
		}
		
		return OPT_CONST::NO_RETURN;
	}
	
	/*
		历史积分榜
	*/
	public function historyScoreboard($arrData)
	{
		$result = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}

		$MMYSQL = $this->initMysql();
		if(isset($data['room_number']) && $data['room_number'] > 0 )
		{
			$room_number = $data['room_number'];
			//判断房间申请记录是否存在
			$room_where = 'room_number='.$room_number;
			$room_sql = 'select room_id,account_id,is_close from '.Room.' where '.$room_where;
			$room_query = $MMYSQL->query($room_sql);
			if(!is_array($room_query) || count($room_query) == 0 )
			{
				$this->writeLog("function(lastScoreboard):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
				return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");  
			}else{
				$room_id = $room_query[0]['room_id'];
			}
		} else if(isset($data['room_id'])&& $data['room_id'] > 0) {
			$room_id = $data['room_id'];
		} else {
			$this->logMessage('error', "function(historyScoreboard):lack of room_id"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_id");
		}

		$scoreboards = array();

		$sql = 'select * from room_scoreboard where room_id='.$room_id.' and game_type='.Game::Game_Type.' order by create_time desc limit 10';
		$query = $MMYSQL->query($sql);
		if(!is_array($query) )
		{
			$this->writeLog("function(historyScoreboard):room($room_id) not exist"." in file".__FILE__." on Line ".__LINE__);
			//return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"没积分榜");  
		}else{
			foreach ($query as $row) {

				$name_board = array();
				$scoreboard = json_decode($row['board']);
				$create_time = $row['create_time'];
				
				if($scoreboard){
					foreach ($scoreboard as $account_id => $score) {
						$account_sql = 'select nickname from '.WX_Account.' where account_id ='.$account_id;
						$name = $MMYSQL->single($account_sql);
						$name_board[] = array('name'=>$name, 'score'=>$score);
					}
					$scoreboards[] = array('time'=>$create_time, 'scoreboard'=>$name_board);
				}
			}
		}
		return array("result"=>"0","operation"=>$operation,"data"=>$scoreboards,"result_message"=>"历史积分榜");  
	}

	/*
		最后一局积分榜
	*/
	public function lastScoreboard($arrData)
	{
		$result = array();
		
		$data 			= $arrData['data'];
		$operation 		= $arrData['operation'];
		$account_id 	= $arrData['account_id'];
		$client_id 		= $arrData['client_id'];

		$session 		= $arrData['session'];
		$Verification_Model = Verification_Model::getModelObject();
		if(false == $Verification_Model->checkRequestSession($account_id,$session))
		{
			return OPT_CONST::NO_RETURN;
		}
		
		if(!(isset($data['room_number'])&& $data['room_number'] > 0) )
		{
			$this->logMessage('error', "function(lastScoreboard):lack of room_number"." in file".__FILE__." on Line ".__LINE__);
			return $this->_missingPrameterArr($operation,"room_number");
		}
		
		$room_number = $data['room_number'];
		$MMYSQL = $this->initMysql();
		//判断房间申请记录是否存在
		$room_where = 'room_number='.$room_number;
		$room_sql = 'select room_id,account_id,is_close from '.Room.' where '.$room_where;
		$room_query = $MMYSQL->query($room_sql);
		if(!is_array($room_query) || count($room_query) == 0 )
		{
			$this->writeLog("function(lastScoreboard):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
			return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>$result,"result_message"=>"房间不存在");  
		}else{
			$room_id = $room_query[0]['room_id'];
		}

		$scoreboards = new stdClass();
		$sql = 'select board,create_time,game_num,rule_text from room_scoreboard where room_id='.$room_id.' and game_type='.Game::Game_Type.' order by create_time desc limit 1';
		$query = $MMYSQL->query($sql);
		if(!is_array($query) )
		{
			$this->writeLog("function(lastScoreboard):room($room_id) not exist"." in file".__FILE__." on Line ".__LINE__); 
		}else{
			foreach ($query as $row) {

				$name_board = array();
				$scoreboard = json_decode($row['board']);
				$create_time = $row['create_time'];
				$game_num = $row['game_num'];

				$total_num = "";
				$rule_text = $row['rule_text'];
				$rule_text_array = explode('局/',$rule_text); 
				if(is_array($rule_text_array) && count($rule_text_array) > 0)
				{
					$total_num = $rule_text_array[0];
				}

				if($scoreboard){
					foreach ($scoreboard as $account_id => $score) {
						$account_sql = 'select nickname from '.WX_Account.' where account_id ='.$account_id;
						$name = $MMYSQL->single($account_sql);
						$name_board[] = array('name'=>$name, 'score'=>$score, 'account_id'=>$account_id);
					}
					$scoreboards = array('time'=>$create_time, 'scoreboard'=>$name_board,'game_num'=>$game_num,'total_num'=>$total_num);
				}
			}
		}
		
		return array("result"=>"0","operation"=>$operation,"data"=>$scoreboards,"result_message"=>"历史积分榜");  
	}
    public function closeRoom($arrData)
    {
        $operation = $arrData['operation'];
        $data = $arrData['data'];
        $account_id = $arrData['account_id'];
        $room_number = $data['room_number'];

        // $current_timer_id = $this->queryTimerId($room_id);
        // if($current_timer_id == $timer_id){
        // 	$this->updateTimer($room_id, -1);
        // } else {
        // 	//timer对不上，返回
        // 	$this->writeLog("function(clearRoomPassive):timer对不上($current_timer_id != $timer_id)"." in file".__FILE__." on Line ".__LINE__);
        // 	return false;
        // }

//        $clients_of_groupid = Gateway::getClientSessionsByGroup($room_id);
//        //判断是否全部人离线
//        if(count($clients_of_groupid) > 0)
//        {
//            $this->writeLog("function(clearRoomPassive):房间($room_id)有人不清理");
//            return false;
//        }

        $MMYSQL = $this->initMysql();

        $room_where = 'room_number='.$room_number.' and is_close =0';
        $room_sql = 'select room_id,account_id,is_close from '.Room.' where '.$room_where;
        $room_query = $MMYSQL->query($room_sql);
        if(!is_array($room_query) || count($room_query) == 0 )
        {
            $this->writeLog("function(closeRoomManager):room($room_number) not exist"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>[],"result_message"=>"房间不存在");
        }else{
            $room_id = $room_query[0]['room_id'];
        }

        if ($room_query[0]['account_id'] != $account_id){
            $this->writeLog("function(closeRoomManager):room($room_number) no auth"." in file".__FILE__." on Line ".__LINE__);
            return array("result"=>OPT_CONST::FAILED,"operation"=>$operation,"data"=>[],"result_message"=>"不是管理员，不能关闭房间");
        }

        $this->writeLog("[$room_id] 触发群主清房间");

        $MMYSQL = $this->initMysql();
        $Redis_Model = Redis_Model::getModelObject();
        $replyArr = array("[roomid]"=>$room_id);
        $RoomScore_Key = strtr(Redis_Const::RoomScore_Key, $replyArr);

        $game_num = $this->queryGameNumber($room_id);
        $creator = $this->queryCreator($room_id);

        if(Config::Ticket_Mode==2 && $game_num==0 && $creator>0){
            $spend_ticket_count = $this->queryTicketCount($room_id);
            $this->balanceTicket($room_id, $creator, - $spend_ticket_count *Config::Ticket_Multi);
        }

        //保存积分榜
        if($game_num > 0){

            $Room_Key = strtr(Redis_Const::Room_Key, $replyArr);
            $round = $Redis_Model->hincrbyField($Room_Key, Redis_Const::Room_Field_GameRound, 1);
            $this->writeLog("[$room_id] 第".($round-1)."轮 结束!");

            $setting = $this->queryRoomSetting($room_id);
            //$round = $setting['ground'];
            $game_info['room_id'] = $room_id;
            $game_info['game_type'] = Game::Game_Type;
            $game_info['round'] = $round-1;

            $scoreboard = array();
            if(isset($setting['scoreboard']) && $setting['scoreboard']){
                $board_json_str = $setting['scoreboard'];
                $scoreboard = json_decode($board_json_str, true); //转为关联数组
            } else {
                //积分榜为空
                $scoreboard = array();
                $board_json_str = "";
            }
            $name_board = array();
            foreach ($scoreboard as $account_id => $score) {
                $account_sql = 'select nickname from '.WX_Account.' where account_id ='.$account_id;
                $name = $MMYSQL->single($account_sql);
                $name_board[] = array('name'=>$name, 'score'=>$score, 'account_id'=>$account_id);
            }

            //规则文本
            $rule_text = $this->formatRuleText($room_id);
            $balance_scoreboard = array('time'=>time(), 'scoreboard'=>$name_board,'game_num'=>$game_num);
            $balance_board_json_str = json_encode($balance_scoreboard['scoreboard']);

            $start_time = $this->queryStartTime($room_id);

            $board_array['start_time'] = $start_time;
            $board_array['create_time'] = time();
            $board_array['is_delete'] = G_CONST::IS_FALSE;
            $board_array['game_type'] = Game::Game_Type;
            $board_array['room_id'] = $room_id;
            $board_array['round'] = $round - 1;
            $board_array['game_num'] = $game_num;
            $board_array['rule_text'] = $rule_text;
            $board_array['board'] = $board_json_str;
            $board_array['balance_board'] = $balance_board_json_str;
            $board_id = $MMYSQL->insertReturnID(Room_Scoreboard,$board_array);

            //保存用户积分
            $game_info['score_board'] = $scoreboard;
            $this->saveAccountGameScore($game_info);
        }
        Gateway::closeCurrentClient();
        $client_list = Gateway::getClientInfoByGroup($room_id);
        foreach ($client_list as $client_id=>$item) {
            Gateway::closeClient($client_id);
        }
        //清理房间
        $this->clearRoom($room_id);

        return true;
    }
}
